/**
 * 模型结构分析工具
 * 用于分析3D模型的各种统计信息
 */

import * as THREE from 'three';
import { GLTFLoader } from '../../lib/three/examples/jsm/loaders/GLTFLoader.js';
import { FBXLoader } from '../../lib/three/examples/jsm/loaders/FBXLoader.js';

/**
 * 模型结构分析器
 */
export class ModelAnalyzer {
    constructor() {
        this.gltfLoader = new GLTFLoader();
        this.fbxLoader = new FBXLoader();
        this.cache = new Map(); // 缓存分析结果
    }

    /**
     * 分析模型结构
     * @param {string} modelId - 模型ID
     * @param {string} projectId - 项目ID
     * @returns {Promise<Object>} 分析结果
     */
    async analyzeModel(modelId, projectId, modelType = 'model') {
        const cacheKey = `${projectId}_${modelId}_${modelType}`;
        
        // 检查缓存
        if (this.cache.has(cacheKey)) {
            return this.cache.get(cacheKey);
        }

        try {
            // 获取模型信息，根据modelType传递type参数
            const typeParam = modelType === 'node' ? '?type=node' : '';
            const response = await fetch(`/api/projects/${projectId}/models/${modelId}${typeParam}`);
            const result = await response.json();
            
            if (!result.success) {
                throw new Error(result.error || '获取模型信息失败');
            }
            
            const modelInfo = result.data;
            const modelPath = `/api/projects/${projectId}/models/${modelId}/file${typeParam}`;
            
            // 加载3D对象
            const object3D = await this.loadModel(modelPath, modelInfo.format);
            
            // 分析结构
            const stats = this.analyzeObject3D(object3D);
            
            // 添加文件信息
            stats.fileInfo = {
                filename: modelInfo.filename,
                format: modelInfo.format,
                size: modelInfo.size,
                uploadTime: modelInfo.uploadTime
            };
            // 缓存结果
            this.cache.set(cacheKey, stats);
            
            return stats;
            
        } catch (error) {
            console.error(`❌ [ModelAnalyzer] 分析模型失败 (${modelId}):`, error);
            
            // 返回错误状态的统计
            const errorStats = {
                error: error.message,
                totalNodes: 0,
                meshCount: 0,
                totalVertices: 0,
                totalTriangles: 0,
                materialCount: 0,
                maxDepth: 0,
                boundingBox: null,
                fileInfo: null
            };
            
            return errorStats;
        }
    }

    /**
     * 根据格式加载模型
     * @param {string} path - 模型路径
     * @param {string} format - 模型格式
     * @returns {Promise<THREE.Object3D>}
     */
    async loadModel(path, format) {
        const extension = format.toLowerCase();
        
        if (extension === 'fbx') {
            return new Promise((resolve, reject) => {
                this.fbxLoader.load(path, resolve, undefined, reject);
            });
        } else if (extension === 'gltf' || extension === 'glb') {
            return new Promise((resolve, reject) => {
                this.gltfLoader.load(path, (gltf) => resolve(gltf.scene), undefined, reject);
            });
        } else {
            throw new Error(`不支持的模型格式: ${format}`);
        }
    }

    /**
     * 分析Object3D结构
     * @param {THREE.Object3D} object3D - 3D对象
     * @returns {Object} 统计信息
     */
    analyzeObject3D(object3D) {
        const stats = {
            totalNodes: 0,
            meshCount: 0,
            totalVertices: 0,
            totalTriangles: 0,
            materialCount: 0,
            maxDepth: 0,
            boundingBox: null,
            nodeTypes: {},
            materialTypes: {}
        };

        const materials = new Set();
        const boundingBox = new THREE.Box3();

        // 递归遍历分析
        const analyzeNode = (node, depth = 0) => {
            stats.totalNodes++;
            stats.maxDepth = Math.max(stats.maxDepth, depth);

            // 统计节点类型
            const nodeType = node.type || 'Object3D';
            stats.nodeTypes[nodeType] = (stats.nodeTypes[nodeType] || 0) + 1;

            // 如果是网格
            if (node.isMesh) {
                stats.meshCount++;

                // 分析几何体
                if (node.geometry) {
                    this.analyzeGeometry(node.geometry, stats);
                }

                // 分析材质
                this.analyzeMaterial(node.material, materials, stats);

                // 更新包围盒
                if (node.geometry) {
                    const nodeBox = new THREE.Box3().setFromObject(node);
                    boundingBox.union(nodeBox);
                }
            }

            // 递归处理子节点
            node.children.forEach(child => analyzeNode(child, depth + 1));
        };

        analyzeNode(object3D);

        // 完成统计
        stats.materialCount = materials.size;
        
        // 计算包围盒信息
        if (!boundingBox.isEmpty()) {
            const size = new THREE.Vector3();
            boundingBox.getSize(size);
            
            stats.boundingBox = {
                min: {
                    x: parseFloat(boundingBox.min.x.toFixed(3)),
                    y: parseFloat(boundingBox.min.y.toFixed(3)),
                    z: parseFloat(boundingBox.min.z.toFixed(3))
                },
                max: {
                    x: parseFloat(boundingBox.max.x.toFixed(3)),
                    y: parseFloat(boundingBox.max.y.toFixed(3)),
                    z: parseFloat(boundingBox.max.z.toFixed(3))
                },
                size: {
                    x: parseFloat(size.x.toFixed(3)),
                    y: parseFloat(size.y.toFixed(3)),
                    z: parseFloat(size.z.toFixed(3))
                }
            };
        }

        return stats;
    }

    /**
     * 分析几何体
     * @param {THREE.BufferGeometry} geometry - 几何体
     * @param {Object} stats - 统计对象
     */
    analyzeGeometry(geometry, stats) {
        // 顶点数
        const positionAttribute = geometry.getAttribute('position');
        if (positionAttribute) {
            stats.totalVertices += positionAttribute.count;
        }

        // 三角形数
        if (geometry.index) {
            // 有索引的几何体
            stats.totalTriangles += geometry.index.count / 3;
        } else if (positionAttribute) {
            // 无索引的几何体
            stats.totalTriangles += positionAttribute.count / 3;
        }
    }

    /**
     * 分析材质
     * @param {THREE.Material|THREE.Material[]} material - 材质
     * @param {Set} materials - 材质集合
     * @param {Object} stats - 统计对象
     */
    analyzeMaterial(material, materials, stats) {
        const mats = Array.isArray(material) ? material : [material];
        
        mats.forEach(mat => {
            if (mat) {
                materials.add(mat.uuid);
                
                // 统计材质类型
                const matType = mat.type || 'Unknown';
                stats.materialTypes[matType] = (stats.materialTypes[matType] || 0) + 1;
            }
        });
    }

    /**
     * 清除缓存
     * @param {string} modelId - 模型ID（可选）
     * @param {string} projectId - 项目ID（可选）
     */
    clearCache(modelId = null, projectId = null) {
        if (modelId && projectId) {
            const cacheKey = `${projectId}_${modelId}`;
            this.cache.delete(cacheKey);
        } else {
            this.cache.clear();
        }
    }

    /**
     * 格式化统计信息用于显示
     * @param {Object} stats - 统计信息
     * @returns {Object} 格式化的显示信息
     */
    formatStatsForDisplay(stats) {
        if (stats.error) {
            return {
                summary: '❌ 分析失败',
                details: stats.error,
                error: true
            };
        }

        // 格式化数字
        const formatNumber = (num) => {
            if (num >= 1000000) return (num / 1000000).toFixed(1) + 'M';
            if (num >= 1000) return (num / 1000).toFixed(1) + 'K';
            return num.toString();
        };

        // 生成摘要
        const summary = [
            `${stats.totalNodes} 节点`,
            `${stats.meshCount} 网格`,
            `${formatNumber(stats.totalVertices)} 顶点`,
            `${stats.materialCount} 材质`
        ].join(' · ');

        // 生成详细信息（去掉重复文字，只保留数值）
        const details = {
            nodes: stats.totalNodes.toString(),
            meshes: stats.meshCount.toString(),
            vertices: formatNumber(stats.totalVertices),
            triangles: formatNumber(Math.round(stats.totalTriangles)),
            materials: stats.materialCount.toString(),
            depth: stats.maxDepth.toString(),
            boundingBox: stats.boundingBox ? 
                `${stats.boundingBox.size.x} × ${stats.boundingBox.size.y} × ${stats.boundingBox.size.z}` : 
                '未知'
        };

        return {
            summary,
            details,
            raw: stats,
            error: false
        };
    }
}

// 创建全局实例
export const modelAnalyzer = new ModelAnalyzer();

// 暴露到全局
window.modelAnalyzer = modelAnalyzer;
